package com.quiz.bis.util.pdf;

import com.quiz.bis.domain.model.PreviewOptions;
import com.quiz.bis.domain.vo.PaperPreviewVO;
import com.quiz.bis.domain.vo.PaperQuestionDetailVO;
import com.quiz.bis.domain.vo.QuestionAnswerVo;
import com.quiz.bis.domain.vo.QuestionOptionVo;
import com.quiz.common.exception.ServiceException;
import com.quiz.common.utils.DateUtils;
import com.quiz.common.utils.StringUtils;
import com.quiz.common.utils.file.FileUtils;
import com.quiz.file.domain.model.FileInfo;
import com.quiz.file.service.IFileService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.util.Units;
import org.apache.poi.xwpf.usermodel.*;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.nodes.Node;
import org.jsoup.nodes.TextNode;
import org.jsoup.select.Elements;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.*;
import org.scilab.forge.jlatexmath.TeXConstants;
import org.scilab.forge.jlatexmath.TeXFormula;
import org.springframework.stereotype.Component;

import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletResponse;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.math.BigInteger;
import java.util.List;
import java.util.Map;

@Slf4j
@Component
@RequiredArgsConstructor
public class ExportPaperWordUtil {

    private final IFileService fileService;
    private Boolean isChoice = false;

    public void exportWord(PaperPreviewVO paper, HttpServletResponse response) {
        try {
            // 设置响应头
            response.setContentType("application/octet-stream");
            FileUtils.setAttachmentResponseHeader(response, paper.getTitle() + ".docx");

            // 创建Word文档
            XWPFDocument document = new XWPFDocument();

            // 添加试卷标题
            XWPFParagraph titlePara = document.createParagraph();
            titlePara.setAlignment(ParagraphAlignment.CENTER);
            XWPFRun titleRun = titlePara.createRun();
            titleRun.setText(paper.getTitle());
            titleRun.setFontSize(18);
            titleRun.setBold(true);

            // 添加试卷信息
            XWPFParagraph infoPara = document.createParagraph();
            infoPara.setAlignment(ParagraphAlignment.CENTER);
            XWPFRun infoRun = infoPara.createRun();
            StringBuilder info = new StringBuilder();
            info.append("总分: ").append(paper.getTotalScore()).append("分  ");
            if (paper.getPassScore() != null) {
                info.append("及格分: ").append(paper.getPassScore()).append("分  ");
            }
            if (paper.getTimeLimit() != null) {
                info.append("考试时长: ").append(paper.getTimeLimit()).append("分钟");
            }
            infoRun.setText(info.toString());
            infoRun.setFontSize(12);

            // 添加试卷说明
            if (StringUtils.isNotBlank(paper.getRemark())) {
                XWPFParagraph remarkPara = document.createParagraph();
                XWPFRun remarkRun = remarkPara.createRun();
                remarkRun.setText("试卷说明: " + paper.getRemark());
                remarkRun.setFontSize(12);
            }

            // 添加题目
            for (Map.Entry<String, List<PaperQuestionDetailVO>> entry : paper.getQuestionsByType().entrySet()) {
                // 添加题型标题
                XWPFParagraph typePara = document.createParagraph();
                typePara.setSpacingBefore(400);
                XWPFRun typeRun = typePara.createRun();
                typeRun.setText(entry.getKey());
                typeRun.setFontSize(14);
                typeRun.setBold(true);

                // 添加题目
                int questionNum = 1;
                for (PaperQuestionDetailVO question : entry.getValue()) {
                    // 题目序号和分值
                    XWPFParagraph questionHeaderPara = document.createParagraph();
                    XWPFRun questionHeaderRun = questionHeaderPara.createRun();
                    questionHeaderRun.setText(questionNum + ". (" + question.getScore() + "分)"+question.getTitle());
                    questionHeaderRun.setFontSize(12);
                    questionHeaderRun.setBold(true);

                    // 题目内容（富文本处理）
                    if (StringUtils.isNotBlank(question.getContent())) {
                        processHtmlContent(document, questionHeaderPara, question.getContent());
                    }

                    // 题目选项
                    if (question.getOptions() != null && !question.getOptions().isEmpty()) {
                        for (QuestionOptionVo option : question.getOptions()) {
                            XWPFParagraph optionPara = document.createParagraph();
                            optionPara.setIndentationLeft(800);
                            XWPFRun optionRun = optionPara.createRun();
                            optionRun.setText(option.getOptionCode() + ". ");
                            optionRun.setBold(true);

                            // 处理选项内容（富文本）
                            if (StringUtils.isNotBlank(option.getContent())) {
                                this.isChoice = true;
                                processHtmlContent(document, optionPara, option.getContent());
                            }

                            // 如果是正确答案且需要显示答案
                            if (paper.getPreviewOptions().isShowOptionAnswers() && option.getIsCorrect() == 1) {
                                XWPFRun correctRun = optionPara.createRun();
                                correctRun.setText(" (正确答案)");
                                correctRun.setColor("00AA00");
                                correctRun.setBold(true);
                            }
                        }
                    }

                    // 题目答案
                    if (paper.getPreviewOptions().isShowAnswers() && question.getAnswers() != null && !question.getAnswers().isEmpty()) {
                        XWPFParagraph answerTitlePara = document.createParagraph();
//                        answerTitlePara.setSpacingBefore(200);
//                        answerTitlePara.setIndentationLeft(400);
                        XWPFRun answerTitleRun = answerTitlePara.createRun();
                        answerTitleRun.setText("答案:");
                        answerTitleRun.setFontSize(12);
                        answerTitleRun.setBold(true);

                        for (QuestionAnswerVo answer : question.getAnswers()) {
//                            XWPFParagraph answerPara = document.createParagraph();
//                            answerPara.setIndentationLeft(800);
                            processHtmlContent(document, answerTitlePara, answer.getContent());
                        }
                    }

                    // 题目解析
                    if (paper.getPreviewOptions().isShowAnalysis() && StringUtils.isNotBlank(question.getAnalysis())) {
                        XWPFParagraph analysisTitlePara = document.createParagraph();
//                        analysisTitlePara.setSpacingBefore(200);
//                        analysisTitlePara.setIndentationLeft(400);
                        XWPFRun analysisTitleRun = analysisTitlePara.createRun();
                        analysisTitleRun.setText("解析:");
                        analysisTitleRun.setFontSize(12);
                        analysisTitleRun.setBold(true);

//                        XWPFParagraph analysisPara = document.createParagraph();
//                        analysisPara.setIndentationLeft(800);
                        processHtmlContent(document, analysisTitlePara, question.getAnalysis());
                    }

                    // 知识点
                    if (paper.getPreviewOptions().isShowKnowledgePoints() && question.getKnowledgePoints() != null && !question.getKnowledgePoints().isEmpty()) {
                        XWPFParagraph knowledgeTitlePara = document.createParagraph();
//                        knowledgeTitlePara.setSpacingBefore(200);
//                        knowledgeTitlePara.setIndentationLeft(400);
                        XWPFRun knowledgeTitleRun = knowledgeTitlePara.createRun();
                        knowledgeTitleRun.setText("知识点:");
                        knowledgeTitleRun.setFontSize(12);
                        knowledgeTitleRun.setBold(true);

//                        XWPFParagraph knowledgePara = document.createParagraph();
//                        knowledgePara.setIndentationLeft(800);
                        XWPFRun knowledgeRun = knowledgeTitlePara.createRun();
                        knowledgeRun.setText(String.join(", ", question.getKnowledgePoints()));
                        knowledgeRun.setFontSize(12);
                    }

                    // 难度
                    if (paper.getPreviewOptions().isShowDifficulty() && question.getDifficult() != null) {
                        XWPFParagraph difficultyTitlePara = document.createParagraph();
//                        difficultyTitlePara.setSpacingBefore(200);
//                        difficultyTitlePara.setIndentationLeft(400);
                        XWPFRun difficultyTitleRun = difficultyTitlePara.createRun();
                        difficultyTitleRun.setText("难度:");
                        difficultyTitleRun.setFontSize(12);
                        difficultyTitleRun.setBold(true);

//                        XWPFParagraph difficultyPara = document.createParagraph();
//                        difficultyPara.setIndentationLeft(800);
                        XWPFRun difficultyRun = difficultyTitlePara.createRun();
                        difficultyRun.setText(getDifficultyText(question.getDifficult()));
                        difficultyRun.setFontSize(12);
                    }

                    questionNum++;
                    document.createParagraph(); // 添加空行
                }
            }

            document.write(response.getOutputStream());
            document.close();
        } catch (Exception e) {
            log.error("导出Word失败", e);
            throw new ServiceException("导出Word失败");
        }
    }

    private void processHtmlContent(XWPFDocument document, XWPFParagraph paragraph, String htmlContent) {
        try {
            Document htmlDoc = Jsoup.parse(htmlContent);
            processNode(document, paragraph, htmlDoc.body());
        } catch (Exception e) {
            log.error("处理HTML内容失败", e);
            paragraph.createRun().setText(htmlContent.replaceAll("<[^>]+>", ""));
        }
    }

    private void processNode(XWPFDocument document, XWPFParagraph paragraph, Node node) {
        if (node instanceof TextNode) {
            String text = ((TextNode) node).text();
            if (!text.trim().isEmpty()) {
                paragraph.createRun().setText(text);
            }
        } else if (node instanceof Element) {
            Element element = (Element) node;
            processElement(document, paragraph, element);
        }
    }

    private void processElement(XWPFDocument document, XWPFParagraph paragraph, Element element) {
        // 处理公式元素
        if (element.hasAttr("data-w-e-type") && "formula".equals(element.attr("data-w-e-type"))) {
            String latex = element.attr("data-value");
            addFormulaToRun(paragraph.createRun(), latex);
            return;
        }

        // 处理图片元素
        if (element.tagName().equalsIgnoreCase("img")) {
            processImage(document, paragraph, element);
            return;
        }

        // 处理其他元素
        switch (element.tagName().toLowerCase()) {
            case "p":
                processParagraph(document, paragraph, element);
                break;
            case "strong":
            case "b":
                processBold(paragraph, element);
                break;
            case "em":
            case "i":
                processItalic(paragraph, element);
                break;
            case "u":
                processUnderline(paragraph, element);
                break;
            case "s":
            case "strike":
                processStrikeThrough(paragraph, element);
                break;
            case "code":
                processCode(paragraph, element);
                break;
            case "sup":
                processSuperscript(paragraph, element);
                break;
            case "sub":
                processSubscript(paragraph, element);
                break;
            case "h1":
            case "h2":
            case "h3":
            case "h4":
            case "h5":
            case "h6":
                processHeading(document, paragraph, element);
                break;
            case "blockquote":
                processBlockquote(document, element);
                break;
            case "ul":
            case "ol":
                processList(document, element);
                break;
            case "table":
                processTable(document, element);
                break;
            case "hr":
                processHorizontalRule(document);
                break;
            case "br":
                paragraph.createRun().addBreak();
                break;
            case "pre":
                processCodeBlock(document, element);
                break;
            case "div":
                if (element.hasAttr("data-w-e-type") && "todo".equals(element.attr("data-w-e-type"))) {
                    processTodo(document, element);
                } else {
                    processDefaultElement(document, paragraph, element);
                }
                break;
            default:
                processDefaultElement(document, paragraph, element);
        }
    }

    private void processParagraph(XWPFDocument document, XWPFParagraph paragraph, Element element) {
        if(!this.isChoice){
            // 创建新段落处理p标签内容
            XWPFParagraph newPara = document.createParagraph();
            newPara.setSpacingAfter(100);

            // 处理子节点
            for (Node child : element.childNodes()) {
                processNode(document, newPara, child);
            }
        }else {
            this.isChoice = false;
            for (Node child : element.childNodes()) {
                processNode(document, paragraph, child);
            }
        }

    }

    private void processBold(XWPFParagraph paragraph, Element element) {
        XWPFRun run = paragraph.createRun();
        run.setBold(true);
        for (Node child : element.childNodes()) {
            if (child instanceof TextNode) {
                run.setText(((TextNode) child).text());
            } else if (child instanceof Element) {
                processElement(run.getDocument(), paragraph, (Element) child);
            }
        }
    }

    private void processItalic(XWPFParagraph paragraph, Element element) {
        XWPFRun run = paragraph.createRun();
        run.setItalic(true);
        for (Node child : element.childNodes()) {
            if (child instanceof TextNode) {
                run.setText(((TextNode) child).text());
            } else if (child instanceof Element) {
                processElement(run.getDocument(), paragraph, (Element) child);
            }
        }
    }

    private void processUnderline(XWPFParagraph paragraph, Element element) {
        XWPFRun run = paragraph.createRun();
        run.setUnderline(UnderlinePatterns.SINGLE);
        for (Node child : element.childNodes()) {
            if (child instanceof TextNode) {
                run.setText(((TextNode) child).text());
            } else if (child instanceof Element) {
                processElement(run.getDocument(), paragraph, (Element) child);
            }
        }
    }

    private void processStrikeThrough(XWPFParagraph paragraph, Element element) {
        XWPFRun run = paragraph.createRun();
        run.setStrikeThrough(true);
        for (Node child : element.childNodes()) {
            if (child instanceof TextNode) {
                run.setText(((TextNode) child).text());
            } else if (child instanceof Element) {
                processElement(run.getDocument(), paragraph, (Element) child);
            }
        }
    }

    private void processCode(XWPFParagraph paragraph, Element element) {
        XWPFRun run = paragraph.createRun();
        run.setColor("808080");
        run.setFontFamily("Courier New");
        for (Node child : element.childNodes()) {
            if (child instanceof TextNode) {
                run.setText(((TextNode) child).text());
            } else if (child instanceof Element) {
                processElement(run.getDocument(), paragraph, (Element) child);
            }
        }
    }

    private void processSuperscript(XWPFParagraph paragraph, Element element) {
        XWPFRun run = paragraph.createRun();
        run.setSubscript(VerticalAlign.SUPERSCRIPT);
        for (Node child : element.childNodes()) {
            if (child instanceof TextNode) {
                run.setText(((TextNode) child).text());
            } else if (child instanceof Element) {
                processElement(run.getDocument(), paragraph, (Element) child);
            }
        }
    }

    private void processSubscript(XWPFParagraph paragraph, Element element) {
        XWPFRun run = paragraph.createRun();
        run.setSubscript(VerticalAlign.SUBSCRIPT);
        for (Node child : element.childNodes()) {
            if (child instanceof TextNode) {
                run.setText(((TextNode) child).text());
            } else if (child instanceof Element) {
                processElement(run.getDocument(), paragraph, (Element) child);
            }
        }
    }

    private void processHeading(XWPFDocument document, XWPFParagraph paragraph, Element element) {
        XWPFParagraph headingPara = document.createParagraph();
        XWPFRun run = headingPara.createRun();
        run.setBold(true);

        int fontSize = 24 - (element.tagName().charAt(1) - '1') * 2;
        run.setFontSize(fontSize);

        for (Node child : element.childNodes()) {
            processNode(document, headingPara, child);
        }
    }

    private void processBlockquote(XWPFDocument document, Element element) {
        XWPFParagraph quotePara = document.createParagraph();
        quotePara.setIndentationLeft(400);
        XWPFRun quoteRun = quotePara.createRun();
        quoteRun.setItalic(true);
        quoteRun.setColor("808080");

        for (Node child : element.childNodes()) {
            processNode(document, quotePara, child);
        }
    }

    private void processList(XWPFDocument document, Element element) {
        boolean isOrdered = element.tagName().equalsIgnoreCase("ol");
        int itemNumber = 1;

        for (Element li : element.select("li")) {
            XWPFParagraph liPara = document.createParagraph();
            XWPFRun liRun = liPara.createRun();

            if (isOrdered) {
                liRun.setText(itemNumber++ + ". ");
            } else {
                liRun.setText("• ");
            }

            for (Node child : li.childNodes()) {
                processNode(document, liPara, child);
            }
        }
    }

    private void processTable(XWPFDocument document, Element element) {
        Elements rows = element.select("tr");
        if (rows.isEmpty()) return;

        // 确定列数
        int cols = rows.first().select("th,td").size();
        if (cols == 0) return;

        // 创建表格
        XWPFTable table = document.createTable(rows.size(), cols);
        table.setWidth("100%");

        // 设置表格边框
        CTTblPr tblPr = table.getCTTbl().addNewTblPr();
        CTTblBorders borders = tblPr.addNewTblBorders();
        setBorder(borders.addNewTop(), STBorder.Enum.forString("single"), 4, "auto");
        setBorder(borders.addNewBottom(), STBorder.Enum.forString("single"), 4, "auto");
        setBorder(borders.addNewLeft(), STBorder.Enum.forString("single"), 4, "auto");
        setBorder(borders.addNewRight(), STBorder.Enum.forString("single"), 4, "auto");
        setBorder(borders.addNewInsideH(), STBorder.Enum.forString("single"), 4, "auto");
        setBorder(borders.addNewInsideV(), STBorder.Enum.forString("single"), 4, "auto");

        // 填充表格内容
        for (int i = 0; i < rows.size(); i++) {
            Elements cells = rows.get(i).select("th,td");
            XWPFTableRow tableRow = table.getRow(i);

            for (int j = 0; j < Math.min(cells.size(), cols); j++) {
                XWPFTableCell cell = tableRow.getCell(j);
                cell.removeParagraph(0); // 清除默认段落

                // 设置单元格属性
                CTTcPr cellProps = cell.getCTTc().addNewTcPr();
                cellProps.addNewTcBorders();

                // 处理单元格内容
                XWPFParagraph cellPara = cell.addParagraph();
                for (Node child : cells.get(j).childNodes()) {
                    processNode(document, cellPara, child);
                }

                // 设置表头样式
                if (cells.get(j).tagName().equalsIgnoreCase("th")) {
                    cellPara.setAlignment(ParagraphAlignment.CENTER);
                    cell.setColor("D3D3D3");
                    for (XWPFRun r : cellPara.getRuns()) {
                        r.setBold(true);
                    }
                }

                cell.setVerticalAlignment(XWPFTableCell.XWPFVertAlign.CENTER);
            }
        }
    }

    private void processImage(XWPFDocument document, XWPFParagraph paragraph, Element element) {
        String src = element.attr("src");
        String alt = element.attr("alt");
        if (StringUtils.isNotEmpty(src)) {
            try {
                // 从src或alt中提取文件ID
                String fileId = extractFileId(src);
                if (StringUtils.isEmpty(fileId)) {
                    fileId = alt;
                }

                if (StringUtils.isNotEmpty(fileId)) {
                    // 获取文件信息
                    FileInfo fileInfo = fileService.getFileById(Long.parseLong(fileId));
                    if (fileInfo != null) {
                        File file = new File(fileInfo.getFilePath());
                        if (file.exists()) {
                            // 读取图片文件
                            byte[] imageData = new byte[(int) file.length()];
                            try (FileInputStream fis = new FileInputStream(file)) {
                                fis.read(imageData);
                            }

                            // 获取图片尺寸
                            int width = 300; // 默认宽度
                            int height = 200; // 默认高度

                            // 尝试从style属性获取宽高
                            if (element.hasAttr("style")) {
                                String style = element.attr("style");
                                String[] styles = style.split(";");
                                for (String s : styles) {
                                    String[] keyValue = s.split(":");
                                    if (keyValue.length == 2) {
                                        String key = keyValue[0].trim();
                                        String value = keyValue[1].trim();
                                        if (key.equals("width")) {
                                            width = (int) Double.parseDouble(value.replaceAll("[^0-9.]", ""));
                                        } else if (key.equals("height")) {
                                            height = (int) Double.parseDouble(value.replaceAll("[^0-9.]", ""));
                                        }
                                    }
                                }
                            }

                            // 添加图片到文档
                            XWPFRun run = paragraph.createRun();
                            run.addPicture(new ByteArrayInputStream(imageData),
                                    XWPFDocument.PICTURE_TYPE_PNG,
                                    "image.png",
                                    Units.toEMU(width),
                                    Units.toEMU(height));
                        }
                    }
                }
            } catch (Exception e) {
                log.error("添加图片失败: " + src, e);
            }
        }
    }

    private String extractFileId(String url) {
        // 从URL中提取文件ID
        if (url.contains("fileId=")) {
            return url.substring(url.indexOf("fileId=") + 7);
        } else if (url.matches(".*\\d{19}.*")) {
            return url.replaceAll(".*?(\\d{19}).*", "$1");
        }
        return null;
    }

    private void processHorizontalRule(XWPFDocument document) {
        XWPFParagraph hrPara = document.createParagraph();
        XWPFRun hrRun = hrPara.createRun();
        hrRun.setText("________________________________________");
    }

    private void processCodeBlock(XWPFDocument document, Element element) {
        XWPFParagraph codePara = document.createParagraph();
        codePara.setIndentationLeft(400);
        codePara.setSpacingAfter(100);

        XWPFRun codeRun = codePara.createRun();
        codeRun.setColor("808080");
        codeRun.setFontFamily("Courier New");
        codeRun.setText(element.text());
    }

    private void processTodo(XWPFDocument document, Element element) {
        XWPFParagraph todoPara = document.createParagraph();
        XWPFRun todoRun = todoPara.createRun();
        todoRun.setText("☐ ");

        // 处理待办内容
        for (Node child : element.childNodes()) {
            if (child instanceof Element && ((Element) child).tagName().equals("span")) {
                processNode(document, todoPara, child);
            }
        }
    }

    private void processDefaultElement(XWPFDocument document, XWPFParagraph paragraph, Element element) {
        XWPFRun run = paragraph.createRun();

        // 处理样式
        if (element.hasAttr("style")) {
            applyStyle(run, element.attr("style"));
        }

        // 处理子节点
        for (Node child : element.childNodes()) {
            processNode(document, paragraph, child);
        }
    }

    private void addFormulaToRun(XWPFRun run, String latex) {
        try {
            // 1. 创建公式
            int dpi = 200;
            TeXFormula.setDPITarget(dpi);
            TeXFormula formula = new TeXFormula(latex);
            float fontSize = 11;
            Color foreground = Color.BLACK;
            Color background = new Color(0, 0, 0, 0); // 透明背景

            // 2. 使用实例方法创建图片
            BufferedImage image = (BufferedImage) formula.createBufferedImage(
                    TeXConstants.STYLE_DISPLAY, fontSize, foreground, Color.white);

            // 3. 裁剪图片周围的空白
            image = trimImage(image);

            // 4. 计算缩放比例，使图片高度与文字行高匹配
            int textHeight = 13; // 大约匹配12号字体的行高
            double scaleFactor = (double) textHeight / image.getHeight();
            int scaledWidth = (int) (image.getWidth() * scaleFactor);
            int scaledHeight = (int) (image.getHeight() * scaleFactor);

            // 5. 缩放图片(不要缩放，会降低画质)
//            BufferedImage scaledImage = new BufferedImage(scaledWidth, scaledHeight, BufferedImage.TYPE_INT_ARGB);
//            Graphics2D g = scaledImage.createGraphics();
//            g.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
//            g.drawImage(image, 0, 0, scaledWidth, scaledHeight, null);
//            g.dispose();

            // 6. 添加图片到文档
            ByteArrayOutputStream bos = new ByteArrayOutputStream();
            ImageIO.write(image, "png", bos);
            byte[] imageData = bos.toByteArray();

            run.addPicture(new ByteArrayInputStream(imageData),
                    XWPFDocument.PICTURE_TYPE_PNG,
                    "formula.png",
                    Units.toEMU(scaledWidth),
                    Units.toEMU(scaledHeight));

            // 7. 调整图片与文本的对齐方式
            run.setTextPosition(-5); // 微调垂直位置
        } catch (Exception e) {
            log.error("公式转换失败: " + latex, e);
            run.setText(" $" + latex + "$ ");
        }
    }
    /**
     * 裁剪图片周围的空白区域
     */
    private BufferedImage trimImage(BufferedImage img) {
        int width = img.getWidth();
        int height = img.getHeight();
        int top = height / 2;
        int bottom = top;
        int left = width / 2;
        int right = left;

        // 确定上边界
        for (int y = 0; y < height; y++) {
            for (int x = 0; x < width; x++) {
                if ((img.getRGB(x, y) & 0xFF000000) != 0) {
                    top = Math.min(top, y);
                    break;
                }
            }
        }

        // 确定下边界
        for (int y = height - 1; y >= 0; y--) {
            for (int x = 0; x < width; x++) {
                if ((img.getRGB(x, y) & 0xFF000000) != 0) {
                    bottom = Math.max(bottom, y);
                    break;
                }
            }
        }

        // 确定左边界
        for (int x = 0; x < width; x++) {
            for (int y = 0; y < height; y++) {
                if ((img.getRGB(x, y) & 0xFF000000) != 0) {
                    left = Math.min(left, x);
                    break;
                }
            }
        }

        // 确定右边界
        for (int x = width - 1; x >= 0; x--) {
            for (int y = 0; y < height; y++) {
                if ((img.getRGB(x, y) & 0xFF000000) != 0) {
                    right = Math.max(right, x);
                    break;
                }
            }
        }

        // 裁剪图片
        return img.getSubimage(left, top, right - left + 1, bottom - top + 1);
    }

    private void setBorder(CTBorder border, STBorder.Enum style, int size, String color) {
        border.setVal(style);
        border.setSz(BigInteger.valueOf(size));
        border.setColor(color);
    }

    private void applyStyle(XWPFRun run, String style) {
        String[] styles = style.split(";");
        for (String s : styles) {
            String[] keyValue = s.split(":");
            if (keyValue.length == 2) {
                String key = keyValue[0].trim();
                String value = keyValue[1].trim();

                switch (key) {
                    case "color":
                        run.setColor(value.replaceAll("[^0-9A-Fa-f]", ""));
                        break;
                    case "background-color":
                        run.setTextHighlightColor(value.replaceAll("[^0-9A-Fa-f]", ""));
                        break;
                    case "font-size":
                        try {
                            int size = Integer.parseInt(value.replaceAll("[^0-9]", ""));
                            run.setFontSize(size);
                        } catch (NumberFormatException e) {
                            // 忽略格式错误
                        }
                        break;
                    case "font-family":
                        run.setFontFamily(value.split(",")[0].replaceAll("['\"]", ""));
                        break;
                    case "text-align":
                        switch (value) {
                            case "left":
                                run.getParagraph().setAlignment(ParagraphAlignment.LEFT);
                                break;
                            case "right":
                                run.getParagraph().setAlignment(ParagraphAlignment.RIGHT);
                                break;
                            case "center":
                                run.getParagraph().setAlignment(ParagraphAlignment.CENTER);
                                break;
                            case "justify":
                                run.getParagraph().setAlignment(ParagraphAlignment.BOTH);
                                break;
                        }
                        break;
                }
            }
        }
    }

    private String getDifficultyText(Integer difficult) {
        if (difficult == null) {
            return "未设置";
        }
        switch (difficult) {
            case 1:
                return "容易";
            case 2:
                return "偏易";
            case 3:
                return "中等";
            case 4:
                return "偏难";
            case 5:
                return "困难";
            default:
                return "未设置";
        }
    }
}